"""
会话模型
支持研究系统的会话管理和持久化
"""

from datetime import datetime
from typing import Optional, List, Dict, Any
import uuid
from enum import Enum
from pydantic import BaseModel, Field
from sqlalchemy import Column, String, DateTime, Boolean, Integer, Text, ForeignKey, JSON, Table
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship, backref
from src.config.database import Base

# 会话和标签的多对多关系表
session_tags = Table(
    'session_tags',
    Base.metadata,
    Column('session_id', UUID(as_uuid=True), ForeignKey('sessions.id'), primary_key=True),
    Column('tag_id', UUID(as_uuid=True), ForeignKey('tags.id'), primary_key=True)
)


class SessionStatus(str, Enum):
    """会话状态枚举"""
    ACTIVE = "active"      # 活跃会话
    CLOSED = "closed"      # 已关闭会话
    EXPIRED = "expired"    # 过期会话


class SessionCategory(str, Enum):
    """会话分类枚举"""
    RESEARCH = "research"      # 研究会话
    CHAT = "chat"              # 聊天会话
    KNOWLEDGE = "knowledge"    # 知识库会话
    DEFAULT = "default"        # 默认分类


class Tag(Base):
    """会话标签模型"""
    __tablename__ = "tags"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(50), nullable=False, unique=True)
    color = Column(String(20), nullable=True, default="#4A90E2")
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    def __repr__(self):
        return f"<Tag {self.id} - {self.name}>"


class Session(Base):
    """会话数据模型"""
    __tablename__ = "sessions"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(100), nullable=False, default="默认会话")
    user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, index=True)
    status = Column(String(20), default=SessionStatus.ACTIVE, nullable=False)
    category = Column(String(20), default=SessionCategory.DEFAULT, nullable=False)  # 会话分类
    interaction_count = Column(Integer, default=0, nullable=False)
    research_count = Column(Integer, default=0, nullable=False)
    session_metadata = Column(JSON, nullable=True)  # 会话元数据
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    closed_at = Column(DateTime, nullable=True)
    search_vector = Column(String(1000), nullable=True)  # 用于全文搜索的向量

    # 关系
    user = relationship("User", backref="sessions")
    interactions = relationship("SessionInteraction", back_populates="session", cascade="all, delete-orphan")
    tags = relationship("Tag", secondary=session_tags, backref=backref("sessions", lazy="dynamic"))

    def __repr__(self):
        return f"<Session {self.id} - {self.name}>"


class SessionInteraction(Base):
    """会话交互记录模型"""
    __tablename__ = "session_interactions"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    session_id = Column(UUID(as_uuid=True), ForeignKey("sessions.id"), nullable=False, index=True)
    question = Column(Text, nullable=False)
    response = Column(JSON, nullable=False)  # 存储完整的响应数据
    processing_time = Column(Integer, nullable=True)  # 处理时间（毫秒）
    success = Column(Boolean, default=True, nullable=False)
    error_message = Column(Text, nullable=True)
    search_strategy = Column(String(100), nullable=True)
    research_complete = Column(Boolean, default=False, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    # 关系
    session = relationship("Session", back_populates="interactions")

    def __repr__(self):
        return f"<SessionInteraction {self.id} - Session {self.session_id}>"


# Pydantic 模型
class SessionCreate(BaseModel):
    """创建会话的请求模型"""
    name: Optional[str] = Field(None, max_length=100, description="会话名称")
    user_id: Optional[uuid.UUID] = Field(None, description="用户ID")
    category: Optional[SessionCategory] = Field(None, description="会话分类")
    metadata: Optional[Dict[str, Any]] = Field(None, description="会话元数据")
    tag_ids: Optional[List[uuid.UUID]] = Field(None, description="标签ID列表")


class SessionUpdate(BaseModel):
    """更新会话的请求模型"""
    name: Optional[str] = Field(None, max_length=100, description="会话名称")
    status: Optional[SessionStatus] = Field(None, description="会话状态")
    category: Optional[SessionCategory] = Field(None, description="会话分类")
    metadata: Optional[Dict[str, Any]] = Field(None, description="会话元数据")


class TagResponse(BaseModel):
    """标签响应模型"""
    id: uuid.UUID
    name: str
    color: Optional[str]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class SessionResponse(BaseModel):
    """会话响应模型"""
    id: uuid.UUID
    name: str
    user_id: Optional[uuid.UUID]
    status: SessionStatus
    category: SessionCategory
    interaction_count: int
    research_count: int
    metadata: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime
    closed_at: Optional[datetime]
    tags: List[TagResponse] = Field(default_factory=list)

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class SessionInteractionCreate(BaseModel):
    """创建交互记录的请求模型"""
    question: str = Field(..., description="用户问题")
    response: Dict[str, Any] = Field(..., description="系统响应")
    processing_time: Optional[int] = Field(None, description="处理时间（毫秒）")
    success: bool = Field(default=True, description="是否成功")
    error_message: Optional[str] = Field(None, description="错误信息")
    search_strategy: Optional[str] = Field(None, description="搜索策略")
    research_complete: bool = Field(default=False, description="研究是否完成")


class SessionInteractionResponse(BaseModel):
    """交互记录响应模型"""
    id: uuid.UUID
    session_id: uuid.UUID
    question: str
    response: Dict[str, Any]
    processing_time: Optional[int]
    success: bool
    error_message: Optional[str]
    search_strategy: Optional[str]
    research_complete: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class SessionStats(BaseModel):
    """会话统计信息模型"""
    session_id: uuid.UUID
    total_interactions: int
    successful_research: int
    failed_research: int
    success_rate: str
    created_at: datetime
    last_updated: datetime
    active: bool


class SessionListResponse(BaseModel):
    """会话列表响应模型"""
    sessions: List[SessionResponse]
    total_count: int
    active_count: int
    closed_count: int


class SessionHistoryResponse(BaseModel):
    """会话历史响应模型"""
    session: SessionResponse
    interactions: List[SessionInteractionResponse]
    total_interactions: int
